<template>
  <div class="goods-sku">
    <dl v-for="(item, i) in specs" :key="i">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="(tag, index) in item.values" :key="index">
          <img :class='{selected: tag.selected,disabled:tag.disabled}' @click='toggle(tag, item.values)' v-if="tag.picture"  :src="tag.picture" />
          <span :class='{selected: tag.selected,disabled:tag.disabled}' @click='toggle(tag, item.values)' v-else >{{ tag.name }}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import powerSet from '@/vendor/power-set.js'
// 规格分隔符
const spliter = '※'

// 生成路径字典
const getPathMap = (skus) => {
  // 路径字典结果
  const result = {}

  skus.forEach(sku => {
    // 过滤掉无效sku数据
    if (sku.inventory === 0) return
    // 获取规格的集合数据：[蓝色，中国，10cm]
    const spec = sku.specs.map(item => item.valueName)
    // 计算当个sku规格的笛卡尔集
    const specSet = powerSet(spec)
    specSet.forEach(item => {
      // 排除空数组
      if (item.length === 0) return
      // 生成字典的key
      const key = item.join(spliter)
      // 把key添加到字典中
      if (result[key]) {
        // 字典中已经存在当前的key
        result[key].push(sku.id)
      } else {
        // 字典中不存在当前的key
        result[key] = [sku.id]
      }
    })
  })

  return result
}

// 获取选中规格的值
const getSelectedValue = (specs) => {
  const result = []
  specs.forEach((item, i) => {
    const spec = item.values.find(tag => tag.selected)
    if (spec) {
      result[i] = spec.name
    } else {
      result[i] = undefined
    }
  })
  return result
}

// 控制标签的禁用状态(判断标签是否应该禁用，如果应该应该禁用就给他添加一个disabled属性)
const updateDisabledStatus = (specs, pathMap) => {
  // 需要把规格的每一个标签都判断一遍
  specs.forEach((item, index) => {
    // 每次遍历不同的规格时，重新获取选中的值
    const result = getSelectedValue(specs) // [undefined, undefined, undefined]
    item.values.forEach(tag => {
      if (tag.selected) {
        // 本来是选中的
        return
      } else {
        result[index] = tag.name
      }
      // 判断此时选中的值是否在路径字典里面
      // 把选中的值组合为路径字典的key
      const pathKey = result.filter(tag => tag).join(spliter)
      // const svalue = result.filter(tag => tag) // [黑色]
      // const pathKey = svalue.join(spliter) // 黑色
      // 判断路径字典中是否有该key
      tag.disabled = !pathMap[pathKey]
    //   console.log(result)
    })
  })
}

// 初始化规格的选中状态（根据skuId）
const initSkuSeletedStatus = (skuId, skus, specs) => {
  // 1、根据SKUId获取对应的sku详细信息
  const currentSku = skus.find(item => item.id === skuId)
  // 2、控制currentSku.specs中的规格进行选中
  specs.forEach(item => {
    // 3、得到需要选中的规格的值
    const selectedValue = currentSku.specs.find(skuItem => skuItem.name === item.name).valueName
    // 4、根据selectedValue控制规格的选中
    item.values.find(tag => tag.name === selectedValue).selected = true
  })
}

export default {
  name: 'GoodsSku',
  props: {
    specs: {
      type: Array,
      default: () => []
    },
    skus: {
      type: Array,
      default: () => []
    },
    skuId: {
      type: String,
      default: ''
    }
  },
  setup (props, { emit }) {
    // 调用封装的字典
    const pathMap = getPathMap(props.skus)
    updateDisabledStatus(props.specs, pathMap)

    // 控制当前标签的选中和反选
    const toggle = (tag, list) => {
      // 如果标签是禁用状态，应该阻止执行后续操作
      if (tag.disabled) return

      // 控制当前
      tag.selected = !tag.selected

      // 排他
      list.forEach(item => {
        if (item.name !== tag.name) {
          item.selected = false
        }
      })

      // 每次切换选中状态，所有的标签都需要再处理一下禁用状态
      updateDisabledStatus(props.specs, pathMap)

      // 获取此时选中的规格的所有的值，传递给父组件
      // 1、如果所有的规格都选择了才是合理的
      // 2、如果有未选的的规格，就不应该得到数据
      const selectedValues = getSelectedValue(props.specs).filter(item => item)
      if (selectedValues.length === props.specs.length) {
        // 规格全部选中了
        const result = {}
        // 根据最终选中的规格值，组合成路径字典key
        const pathKey = selectedValues.join(spliter)
        // 根据路径key获取skuId
        const skuId = pathMap[pathKey][0]
        // 根据skuId从skus中获取详细数据
        const skuInfo = props.skus.find(item => item.id === skuId)
        // 准备商品数据
        result.skuId = skuId
        result.price = skuInfo.price
        result.oldPrice = skuInfo.oldPrice
        result.inventory = skuInfo.inventory
        // 拼接规格数据
        // result.specsText = '颜色:黑色;产地:中国;尺寸:10cm'
        // let specsText = ''
        // skuInfo.specs.forEach(item => {
        //   specsText += item.name + ':' + item.valueName + ';'
        // })
        // result.specsText = specsText
        // -------------------------------------
        result.specsText = skuInfo.specs.reduce((result, item) => result + item.name + ':' + item.valueName + ';', '')
        emit('update-info', result)
      } else {
        // 规格没有全部选中
        emit('update-info', {})
      }
    }

    // 从购物车进入商品详情默认选中
    if (props.skuId) {
      initSkuSeletedStatus(props.skuId, props.skus, props.specs)
    }

    return { toggle }
  }
}

</script>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
